package com.wsoft.bpm.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.wsoft.bpm.entity.ActWorkflowConfigEntity;
import com.wsoft.bpm.query.node.*;
import com.wsoft.bpm.service.IActWorkflowConfigService;
import com.wsoft.constant.CommonConstant;
import com.wsoft.core.service.RedisService;
import com.wsoft.entity.BaseEntity;
import com.wsoft.response.ResponseResult;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.log4j.Log4j2;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author zhonglj
 * @date 2024-09-19 16:05
 **/
@Log4j2
@RestController
@Tag(name = "BPMN节点定义")
@RequestMapping("/bpm/def")
public class BpmDefController {
    @Resource
    private IActWorkflowConfigService actWorkflowConfigService;
    @Resource
    private RedisService redisService;

    @Operation(summary = "开始", description = "开始")
    @PostMapping("/startEvent")
    public ResponseResult<String> startEvent(@RequestBody @Validated StartEventQuery req) {
        String xmlData = actWorkflowConfigService.convertXmlStartEvent(req);
        return ResponseResult.success(xmlData);
    }


    @Operation(summary = "连接线", description = "连接线")
    @PostMapping("/sequenceFlow")
    public ResponseResult<String> sequenceFlow(@RequestBody @Validated SequenceFlowQuery req) {
        String xmlData = actWorkflowConfigService.convertXmlSequenceFlow(req);
        return ResponseResult.success(xmlData);
    }

    @Operation(summary = "网关", description = "网关")
    @PostMapping("/gateway")
    public ResponseResult<String> gateway(@RequestBody @Validated GateWayQuery req) {
        String xmlData = actWorkflowConfigService.convertXmlGateWay(req);
        return ResponseResult.success(xmlData);
    }

    @Operation(summary = "用户任务", description = "用户任务")
    @PostMapping("/userTask")
    public ResponseResult<String> task(@RequestBody @Validated TaskQuery req) {
        String xmlData = actWorkflowConfigService.convertXmlUserTask(req);
        return ResponseResult.success(xmlData);
    }

    @Operation(summary = "定时边界事件", description = "定时边界事件")
    @PostMapping("/timeBoundaryEvent")
    public ResponseResult<String> timeBoundaryEvent(@RequestBody @Validated TimeBoundaryEventQuery req) {
        String xmlData = actWorkflowConfigService.convertXmlTimeBoundaryEvent(req);
        return ResponseResult.success(xmlData);
    }

    @Operation(summary = "定时中间件事件", description = "定时中间件事件")
    @PostMapping("/timeIntermediateEvent")
    public ResponseResult<String> timeIntermediateEvent(@RequestBody @Validated TimeIntermediateEventQuery req) {
        String xmlData = actWorkflowConfigService.convertXmlTimeIntermediateEvent(req);
        return ResponseResult.success(xmlData);
    }

    @Operation(summary = "消息边界事件", description = "消息边界事件")
    @PostMapping("/messageBoundaryEvent")
    public ResponseResult<String> messageBoundaryEvent(@RequestBody @Validated MessageBoundaryEventQuery req) {
        String xmlData = actWorkflowConfigService.convertXmlMessageBoundaryEvent(req);
        return ResponseResult.success(xmlData);
    }

    @Operation(summary = "消息中间件事件", description = "消息中间件事件")
    @PostMapping("/messageIntermediateEvent")
    public ResponseResult<String> messageIntermediateEvent(@RequestBody @Validated MessageIntermediateEventQuery req) {
        String xmlData = actWorkflowConfigService.convertXmlMessageIntermediateEvent(req);
        return ResponseResult.success(xmlData);
    }

    @Operation(summary = "结束", description = "结束")
    @PostMapping("/endEvent")
    public ResponseResult<String> endEvent(@RequestBody @Validated EndEventQuery req) {
        String xmlData = actWorkflowConfigService.convertXmlEndEvent(req);
        return ResponseResult.success(xmlData);
    }

    @Operation(summary = "处理流程", description = "处理流程")
    @PostMapping("/process")
    public ResponseResult<String> process(@RequestBody @Validated ProcessQuery req) {
        String xmlData = actWorkflowConfigService.convertXmlProcess(req);
        return ResponseResult.success(xmlData);
    }

    @Operation(summary = "退出流程设计器清理缓存", description = "退出流程设计器清理缓存")
    @PostMapping("/clearModelCache")
    public ResponseResult clearModelCache(@RequestBody @Validated ProcessQuery req) {
        actWorkflowConfigService.clearModelCache(req);
        return ResponseResult.success("[sys.msg.success]");
    }

    @Operation(summary = "获取节点json配置数据", description = "根据activityId（节点id）获取节点json配置数据")
    @GetMapping("/config")
    public ResponseResult<JSONObject> getConfigById(@RequestParam String activityId, @RequestParam(required = false) String procDefId) {
        if (StrUtil.isBlank(procDefId)) {
            // 最新数据的保存首先从缓存获取
            List<Object> byKeyPattern = redisService.getByKeyPattern("*" + activityId);
            if (CollUtil.isNotEmpty(byKeyPattern)) {
                return ResponseResult.success(new JSONObject(byKeyPattern.get(0).toString()));
            }
        }

        // 数据库获取
        ActWorkflowConfigEntity entity = actWorkflowConfigService.getOne(
                Wrappers.lambdaQuery(ActWorkflowConfigEntity.class)
                        .eq(ActWorkflowConfigEntity::getActId, activityId)
                        .eq(BaseEntity::getDeleted, CommonConstant.YESNO_NO)
                        // 部署id是否为空来执行不同sql查询
                        .eq(StrUtil.isNotBlank(procDefId), ActWorkflowConfigEntity::getProcDefId, procDefId)
                        .isNull(StrUtil.isBlank(procDefId), ActWorkflowConfigEntity::getProcDefId)
        );

        if (entity == null || StrUtil.isBlank(entity.getJson())) {
            log.error("[bpm.def.error.empty.configJson]");
            return ResponseResult.success(new JSONObject());
        }

        return ResponseResult.success(JSONUtil.parseObj(entity.getJson()));
    }
}
